
/* --------------------------------------- Include Files ---------------------------------------- */
//#include "common.h"
#include "stm32f10x.h"
#include "system_timer.h"
#include "crc16.h"
#include "sip.h"
#include "driver.h"

/* ---------------------------------------- Macro Defines --------------------------------------- */


/* --------------------------------- Global Function Prototypes --------------------------------- */
SIP_FRAME Sip_createFrame(uint8_t type,uint8_t* content,uint16_t content_length);
uint32_t Sip_parseFrame(SIP_PARSE_STATE* parse_state, void (*handler_fun)(SIP_PARSE_STATE*), uint8_t rxdata);
/* --------------------------------- Private Function Prototypes -------------------------------- */


/* -------------------------------------- Static Variables -------------------------------------- */


/*************************************************************************************************
 * Procedure: Sip_createFrame
 * Object: 创建SIP帧
 * Parameters In:
 *  - none      
 * Parameters Out:
 * - none
 *************************************************************************************************/
SIP_FRAME Sip_createFrame(uint8_t type,uint8_t* content,uint16_t content_length)
{
	  uint32_t counter = 0;
	  uint16_t temp = 0;
	  SIP_FRAME data;
	
	  /* Header */
	  data.header[0] = 0xA5;                                                        
	  data.header[1] = 0x5A;
	
	  /* Type */
	  data.type[0] = type;
	
	  /* Length */
	  data.length[0] = (uint8_t)((content_length+7)&0XFF);                          
	  data.length[1] = (uint8_t)(((content_length+7)>>8)&0XFF);
	
	  /* content */
	  for(counter=0; counter<content_length; counter++){
		  data.content_and_checksum[counter] = *(content+counter);
	  }
	  
	  /* crc */
	  temp = Crc_cal(&data.header[0], content_length+5);
	  data.content_and_checksum[content_length] = (uint8_t)(temp&0XFF);
	  data.content_and_checksum[content_length+1] = (uint8_t)((temp>>8)&0XFF);
		
		#if HEX2STR
		for(int i = 0;i < 2;i++){
			USART1_to_string(data.header[i]);
		}
		for(int i = 0;i < 1;i++){
			USART1_to_string(data.type[i]);
		}
		for(int i = 0;i < 2;i++){
			USART1_to_string(data.length[i]);
		}
		for(int i = 0;i < content_length;i++){
			USART1_to_string(data.content_and_checksum[i]);
		}
		USART1_to_string(data.content_and_checksum[content_length]);
		USART1_to_string(data.content_and_checksum[content_length+1]);
		#else
		#endif

	  return data;
}


/**
  * @brief Sip_parseFrame
  * @param  
  * @retval 
  * @note   解析SIP帧
  */
uint32_t Sip_parseFrame(SIP_PARSE_STATE* parse_state, void (*handler_fun)(SIP_PARSE_STATE*), uint8_t rxdata)
{
	switch(parse_state->state){
		// Header
	    case 0X01:{
			if(parse_state->pt == 0){
				if(rxdata == 0xA5){
					parse_state->rxframe.header[0] = rxdata;
					parse_state->pt++;
				}else{
					parse_state->pt = 0;
					parse_state->state = 0X01;
					return 0x00;
				}
			}else if(parse_state->pt == 1){
				if(rxdata == 0x5A){
					parse_state->rxframe.header[1] = rxdata;
					parse_state->pt++;
					parse_state->state = 0X02;
				}else{
					parse_state->pt = 0;
					parse_state->state = 0X01;
					return 0x00;
				}
			}
		}
		break;
		
		// TYPE
	    case 0X02:{
			if(parse_state->pt == 2){
			    parse_state->rxframe.type[0] = rxdata;
				parse_state->type = rxdata;
				parse_state->pt++;
				parse_state->state = 0X03;
			}else{
			    parse_state->pt = 0;
				parse_state->state = 0X01;
				return 0x00;
			}
		}
		break;
		
		// LENGTH
	    case 0X03:{
			if(parse_state->pt == 3){
				parse_state->rxframe.length[0] = rxdata;
				parse_state->pt++;
			}else if(parse_state->pt == 4){
				parse_state->rxframe.length[1] = rxdata;
				parse_state->pt++;
				parse_state->length = (uint16_t)parse_state->rxframe.length[0]+((uint16_t)parse_state->rxframe.length[1])*256;
				if(parse_state->length<7){                                   // 检查数据包长度
					parse_state->pt = 0;
					parse_state->state = 0X01;
					return 0x00;
				}else if((parse_state->length-7)>512){
					parse_state->pt = 0;
					parse_state->state = 0X01;
					return 0x00;
				}else{
					parse_state->content_length = parse_state->length-7;    // 内容长度
					parse_state->state = 0X04;
				}
			}else{
				parse_state->pt = 0;
				parse_state->state = 0X01;
				return 0x00;
			}			
		}
		break;
		
			// CONTENT		
	    case 0X04:{
			if((parse_state->pt>=5)&&(parse_state->pt<(parse_state->length-2))){
				parse_state->rxframe.content_and_checksum[parse_state->pt-5] = rxdata;
				parse_state->pt++;
				if(parse_state->pt==(parse_state->length-2)){
					parse_state->state = 0X05;
				}
			}else{
				parse_state->pt = 0;
				parse_state->state = 0X01;
				return 0x00;
			}			
		}
		break;
		
		// CHECK SUM
	    case 0X05:{
			if(parse_state->pt==(parse_state->length-2)){
				parse_state->rxframe.content_and_checksum[parse_state->content_length] = rxdata;
				parse_state->checksum = (uint16_t)rxdata&(0X00FF);
				parse_state->pt++;
			}else if(parse_state->pt==(parse_state->length-1)){
				parse_state->rxframe.content_and_checksum[parse_state->content_length+1] = rxdata;
				parse_state->checksum = parse_state->checksum + (uint16_t)(rxdata&0X00FF)*256;
				parse_state->pt++;
				if(Crc_cal((uint8_t*)&parse_state->rxframe,parse_state->length-2)==parse_state->checksum){						 
					(*handler_fun)(parse_state);              // handler
					parse_state->pt = 0;                      // reset state
					parse_state->state = 0X01;
					return 0x01;
				}else{
					parse_state->pt = 0;
					parse_state->state = 0X01;
					return 0x00;
				}
			}else{
				parse_state->pt = 0;
				parse_state->state = 0X01;
				return 0x00;
			}			
		}
		break;
		
		// DEFAULT
		default:{
			parse_state->pt = 0;
			parse_state->state = 0X01;
		}
	    break;
		
		}
}

